import java.lang.Math;
import java.util.Calendar;
import java.util.GregorianCalendar;
import java.util.ArrayList;
/**
* Diese Klasse stellt eine Messstelle dar, �ber ihr kann man Messwerte zu einer Liste von Messwerten hinzuf�gen und Statistiken �ber diese Liste anzeigen lassen.
*
* @author Andrei Borza, e0625499, 532, TU Wien, e0625499@student.tuwien.ac.at
*
*/
public class MeasuringPoint {
public static final double MINVALUE = 0;
public static final double MAXVALUE = 500;
public static final double BORDERVALUE = 120;
public static final GregorianCalendar MINTIME = new GregorianCalendar(2000, 0, 1); // YYYY, MM, DD (MM: 0-11)
public static final GregorianCalendar MAXTIME = new GregorianCalendar(2100, 11, 31);
private ArrayList<MeasureValue> measureValues = new ArrayList<MeasureValue>();
/**
* F�gt einen Messwert der Liste hinzu falls keine Fehler aufgetreten sind.
*
* @param value Einzuf�gender Messwert
* @return Fehlermeldung falls Wert ung�ltig, Fehlermeldung falls die letzten zwei Werte �ber dem Grenzwert sind, Fehlermeldung falls die Eintragezeit vor der Eintragezeit der letzten Messung liegt, null falls alles erfolgreich ist
*/
public String add(MeasureValue value){
String retArg = "";
if(isMeasureValueValid(value) == null){
//Erster Wert wird hinzugef�gt
if(this.measureValues.isEmpty()){
this.measureValues.add(value);
} else{
//F�ge nur hinzu falls der Eingabezeitpunkt nach dem Eingabezeitpunkt des letzten eingetragenen Wertes liegt
GregorianCalendar lastTime = this.measureValues.get(this.measureValues.size()-1).getTime();
if(value.getTime().after(lastTime)){
this.measureValues.add(value);
//�berpr�fe die momentane Liste
if(isTwoMeasureValuesOverBorder()){
retArg += "\nLast two values over border";
}
if(isHalfOverBorder()){
retArg += "\nAverage of the values in the last hour over border";
}
} else{
return "This time is earlier or equal than the last time";
}
}
} else{
//Fehlerausgabe
return isMeasureValueValid(value);
}
//Hinzuf�gung erfolgreich falls retArg leer
if(retArg.equals("")){
return null;
} else{
return retArg.substring(1);
}
}
/**
* Kontrolliert ob Eingabedaten valide sind
*
* @param value Zu �bergebender Messwert
* @return Fehlermeldung wenn nicht plausibel, sonst null
*/
public String isMeasureValueValid(MeasureValue value) {
String retArg = "";
if (MeasuringPoint.MINVALUE > value.getValue() || MeasuringPoint.MAXVALUE < value.getValue()) {
retArg += "\nValue is not plausible";
}
if (value.getTime().after(MeasuringPoint.MAXTIME) || value.getTime().before(MeasuringPoint.MINTIME)) {
retArg += "\nTime is not plausible";
}
if (retArg.equals("")) {
if (MeasuringPoint.BORDERVALUE*2 < value.getValue()) {
return "Value twice over border";
}
else {
return null;
}
}
else {
return retArg.substring(1);
}
}
/**
* L�scht einen Messwert aus der Liste.
*
* @param value Zu entfernender Messwert
* @return Fehlermeldung falls Messwert nicht gefunden, ansonsten null
*/
public String remove(MeasureValue value){
if(this.measureValues.contains(value)){
this.measureValues.remove(measureValues.indexOf(value));
} else{
return "No value found";
}
//L�schung erfolgreich
return null;
}
/**
* Sind die letzten beiden Messwerte �ber dem Grenzwert?
*
* @return True falls ja, False falls nein
*/
private boolean isTwoMeasureValuesOverBorder(){
if(this.measureValues.size() >= 2){
if(this.measureValues.get(this.measureValues.size()-1).getValue() > MeasuringPoint.BORDERVALUE && this.measureValues.get(this.measureValues.size()-2).getValue() > MeasuringPoint.BORDERVALUE){
return true;
}
}
return false;
}
/**
* Liegen mehr als die H�lfte der innerhalb letzten Stunde gemessenen Werte �ber den Grenzwert? (Mindestens 5 Messungen)
*
* @return true falls ja, false falls nicht
*/
private boolean isHalfOverBorder(){
int counter = 0;
int bcounter = 0;
GregorianCalendar lowerBorder = (GregorianCalendar)this.measureValues.get(this.measureValues.size()-1).getTime().clone();
lowerBorder.roll(GregorianCalendar.HOUR,-1);
if (this.measureValues.size() > 0) {
for (int i = this.measureValues.size()-1; i >= 0; i--) {
if (lowerBorder.before(this.measureValues.get(i).getTime()) ||
lowerBorder.equals(this.measureValues.get(i).getTime())) {
counter++;
if (this.measureValues.get(i).getValue() > MeasuringPoint.BORDERVALUE) {
bcounter++;
}
}
else {
break;
}
}
}
else {
return false;
}
if (bcounter != 0) {
if ((double)bcounter/(double)counter > 0.5 && counter >= 5) {
return true;
}
else {
return false;
}
}
else {
return false;
}
}
/**
* Listet alle Werte in einem bestimmten Zeitraum.
*
* @param from Anfang des Zeitraums
* @param to Ende des Zeitraums
* @return Fehlermeldungen falls es keine Werte f�r die eingegebenen Zeiten gibt, ansonsten werden alle im Zeitraum existierenden Werte ausgegeben
*/
public String printMeasureValues(GregorianCalendar from, GregorianCalendar to){
String values= "";
if (from.after(to)){
return "Interval is not valid";
}
if (measureValues.size() == 0) {
return "No values in interval";
}
for (int i = 0; i < measureValues.size(); i++) {
if (measureValues.get(i).getTime().after(to)) {
break;
}
if(measureValues.get(i).getTime().after(from) ||
measureValues.get(i).getTime().equals(from)) {
values += "\n" + measureValues.get(i).toString();
}
}
if (values.equals("")) {
return "No values in interval";
}
else {
return values.substring(1);
}
}
/**
* Abfrage des Durschnitts aller in einem bestimmten Zeitraum gemessenen Werte
*
* @param from Anfang des Zeitraums
* @param to Ende des Zeitraums
* @return Fehlermeldungen falls es keine Werte f�r die eingegebenen Zeiten gibt, ansonsten das Arithmetische Mittel aller in dem Zeitraum eingetragenen Werte
*/
public String printAverage(GregorianCalendar from, GregorianCalendar to){
double value = 0;
int count = 0;
if (from.after(to)){
return "Interval is not valid";
}
if (measureValues.size() == 0) {
return "No values in interval";
}
for (int i = 0; i < measureValues.size(); i++) {
if (measureValues.get(i).getTime().after(to)) {
break;
}
if(measureValues.get(i).getTime().after(from) ||
measureValues.get(i).getTime().equals(from)) {
count++;
value += measureValues.get(i).getValue();
}
}
if (count == 0) {
return "No values in interval";
}
else {
return Double.toString((value/count));
}
}
}